home *** CD-ROM | disk | FTP | other *** search
/ isnet Internet / Isnet Internet CD.iso / prog / hiz / 09 / 09.exe / adynware.exe / perl / lib / Sys / Syslog.pm < prev   
Encoding:
Perl POD Document  |  1999-12-28  |  6.5 KB  |  253 lines

  1. package Sys::Syslog;
  2. require 5.000;
  3. require Exporter;
  4. use Carp;
  5.  
  6. @ISA = qw(Exporter);
  7. @EXPORT = qw(openlog closelog setlogmask syslog);
  8.  
  9. use Socket;
  10. use Sys::Hostname;
  11.  
  12.  
  13. =head1 NAME
  14.  
  15. Sys::Syslog, openlog, closelog, setlogmask, syslog - Perl interface to the UNIX syslog(3) calls
  16.  
  17. =head1 SYNOPSIS
  18.  
  19.     use Sys::Syslog;
  20.  
  21.     openlog $ident, $logopt, $facility;
  22.     syslog $priority, $format, @args;
  23.     $oldmask = setlogmask $mask_priority;
  24.     closelog;
  25.  
  26. =head1 DESCRIPTION
  27.  
  28. Sys::Syslog is an interface to the UNIX C<syslog(3)> program.
  29. Call C<syslog()> with a string priority and a list of C<printf()> args
  30. just like C<syslog(3)>.
  31.  
  32. Syslog provides the functions:
  33.  
  34. =over
  35.  
  36. =item openlog $ident, $logopt, $facility
  37.  
  38. I<$ident> is prepended to every message.
  39. I<$logopt> contains one or more of the words I<pid>, I<ndelay>, I<cons>, I<nowait>.
  40. I<$facility> specifies the part of the system
  41.  
  42. =item syslog $priority, $format, @args
  43.  
  44. If I<$priority> permits, logs I<($format, @args)>
  45. printed as by C<printf(3V)>, with the addition that I<%m>
  46. is replaced with C<"$!"> (the latest error message).
  47.  
  48. =item setlogmask $mask_priority
  49.  
  50. Sets log mask I<$mask_priority> and returns the old mask.
  51.  
  52. =item setlogsock $sock_type
  53.  
  54. Sets the socket type to be used for the next call to
  55. C<openlog()> or C<syslog()>.
  56.  
  57. A value of 'unix' will connect to the UNIX domain socket returned
  58. by C<_PATH_LOG> in F<syslog.ph>.  A value of 'inet' will connect
  59. to an INET socket returned by getservbyname().
  60. Any other value croaks.
  61.  
  62. The default is for the INET socket to be used.
  63.  
  64.  
  65. =item closelog
  66.  
  67. Closes the log file.
  68.  
  69. =back
  70.  
  71. Note that C<openlog> now takes three arguments, just like C<openlog(3)>.
  72.  
  73. =head1 EXAMPLES
  74.  
  75.     openlog($program, 'cons,pid', 'user');
  76.     syslog('info', 'this is another test');
  77.     syslog('mail|warning', 'this is a better test: %d', time);
  78.     closelog();
  79.  
  80.     syslog('debug', 'this is the last test');
  81.  
  82.     setlogsock('unix');
  83.     openlog("$program $$", 'ndelay', 'user');
  84.     syslog('notice', 'fooprogram: this is really done');
  85.  
  86.     setlogsock('inet');
  87.     $! = 55;
  88.     syslog('info', 'problem was %m'); # %m == $! in syslog(3)
  89.  
  90. =head1 DEPENDENCIES
  91.  
  92. B<Sys::Syslog> needs F<syslog.ph>, which can be created with C<h2ph>.
  93.  
  94. =head1 SEE ALSO
  95.  
  96. L<syslog(3)>
  97.  
  98. =head1 AUTHOR
  99.  
  100. Tom Christiansen E<lt>F<tchrist@perl.com>E<gt> and Larry Wall E<lt>F<larry@wall.org>E<gt>.
  101. UNIX domain sockets added by Sean Robinson E<lt>F<robinson_s@sc.maricopa.edu>E<gt>
  102. with support from Tim Bunce <Tim.Bunce@ig.co.uk> and the perl5-porters mailing list.
  103.  
  104. =cut
  105.  
  106. require 'syslog.ph';
  107.  
  108. $maskpri = &LOG_UPTO(&LOG_DEBUG);
  109.  
  110. sub openlog {
  111.     ($ident, $logopt, $facility) = @_;  # package vars
  112.     $lo_pid = $logopt =~ /\bpid\b/;
  113.     $lo_ndelay = $logopt =~ /\bndelay\b/;
  114.     $lo_cons = $logopt =~ /\bcons\b/;
  115.     $lo_nowait = $logopt =~ /\bnowait\b/;
  116.     &connect if $lo_ndelay;
  117.  
  118. sub closelog {
  119.     $facility = $ident = '';
  120.     &disconnect;
  121.  
  122. sub setlogmask {
  123.     local($oldmask) = $maskpri;
  124.     $maskpri = shift;
  125.     $oldmask;
  126. }
  127.  
  128. sub setlogsock {
  129.     local($setsock) = shift;
  130.     if (lc($setsock) eq 'unix') {
  131.         $sock_unix = 1;
  132.     } elsif (lc($setsock) eq 'inet') {
  133.         undef($sock_unix);
  134.     } else {
  135.         croak "Invalid argument passed to setlogsock; must be 'unix' or 'inet'";
  136.     }
  137. }
  138.  
  139. sub syslog {
  140.     local($priority) = shift;
  141.     local($mask) = shift;
  142.     local($message, $whoami);
  143.     local(@words, $num, $numpri, $numfac, $sum);
  144.     local($facility) = $facility;    # may need to change temporarily.
  145.  
  146.     croak "syslog: expected both priority and mask" unless $mask && $priority;
  147.  
  148.     @words = split(/\W+/, $priority, 2);# Allow "level" or "level|facility".
  149.     undef $numpri;
  150.     undef $numfac;
  151.     foreach (@words) {
  152.     $num = &xlate($_);        # Translate word to number.
  153.     if (/^kern$/ || $num < 0) {
  154.         croak "syslog: invalid level/facility: $_";
  155.     }
  156.     elsif ($num <= &LOG_PRIMASK) {
  157.         croak "syslog: too many levels given: $_" if defined($numpri);
  158.         $numpri = $num;
  159.         return 0 unless &LOG_MASK($numpri) & $maskpri;
  160.     }
  161.     else {
  162.         croak "syslog: too many facilities given: $_" if defined($numfac);
  163.         $facility = $_;
  164.         $numfac = $num;
  165.     }
  166.     }
  167.  
  168.     croak "syslog: level must be given" unless defined($numpri);
  169.  
  170.     if (!defined($numfac)) {    # Facility not specified in this call.
  171.     $facility = 'user' unless $facility;
  172.     $numfac = &xlate($facility);
  173.     }
  174.  
  175.     &connect unless $connected;
  176.  
  177.     $whoami = $ident;
  178.  
  179.     if (!$whoami && $mask =~ /^(\S.*?):\s?(.*)/) {
  180.     $whoami = $1;
  181.     $mask = $2;
  182.     } 
  183.  
  184.     unless ($whoami) {
  185.     ($whoami = getlogin) ||
  186.         ($whoami = getpwuid($<)) ||
  187.         ($whoami = 'syslog');
  188.     }
  189.  
  190.     $whoami .= "[$$]" if $lo_pid;
  191.  
  192.     $mask =~ s/%m/$!/g;
  193.     $mask .= "\n" unless $mask =~ /\n$/;
  194.     $message = sprintf ($mask, @_);
  195.  
  196.     $sum = $numpri + $numfac;
  197.     unless (send(SYSLOG,"<$sum>$whoami: $message\0",0)) {
  198.     if ($lo_cons) {
  199.         if ($pid = fork) {
  200.         unless ($lo_nowait) {
  201.             $died = waitpid($pid, 0);
  202.         }
  203.         }
  204.         else {
  205.         open(CONS,">/dev/console");
  206.         print CONS "<$facility.$priority>$whoami: $message\r";
  207.         exit if defined $pid;        # if fork failed, we're parent
  208.         close CONS;
  209.         }
  210.     }
  211.     }
  212. }
  213.  
  214. sub xlate {
  215.     local($name) = @_;
  216.     $name = uc $name;
  217.     $name = "LOG_$name" unless $name =~ /^LOG_/;
  218.     $name = "Sys::Syslog::$name";
  219.     defined &$name ? &$name : -1;
  220. }
  221.  
  222. sub connect {
  223.     unless ($host) {
  224.     require Sys::Hostname;
  225.     my($host_uniq) = Sys::Hostname::hostname();
  226.     ($host) = $host_uniq =~ /([A-Za-z0-9_.-]+)/; # allow FQDN (inc _)
  227.     }
  228.     unless ( $sock_unix ) {
  229.         my $udp = getprotobyname('udp');
  230.         my $syslog = getservbyname('syslog','udp');
  231.         my $this = sockaddr_in($syslog, INADDR_ANY);
  232.         my $that = sockaddr_in($syslog, inet_aton($host) || croak "Can't lookup $host");
  233.         socket(SYSLOG,AF_INET,SOCK_DGRAM,$udp)           || croak "socket: $!";
  234.         connect(SYSLOG,$that)                            || croak "connect: $!";
  235.     } else {
  236.         my $syslog = &_PATH_LOG                          || croak "_PATH_LOG not found in syslog.ph";
  237.         my $that = sockaddr_un($syslog)                  || croak "Can't locate $syslog";
  238.         socket(SYSLOG,AF_UNIX,SOCK_STREAM,0)             || croak "open: $!";
  239.         connect(SYSLOG,$that)                            || croak "connect: $!";
  240.     }
  241.     local($old) = select(SYSLOG); $| = 1; select($old);
  242.     $connected = 1;
  243. }
  244.  
  245. sub disconnect {
  246.     close SYSLOG;
  247.     $connected = 0;
  248. }
  249.  
  250. 1;
  251.